<?php
/**
 * FILE NAME WeekList.php
 */
require_once dirname( __FILE__ ).'/Controller.php';
require_once dirname(__FILE__) . '/Mapper.php';
require_once 'Request/DateTime.php';
require_once 'Smarty/Components/anchor.php';
require_once 'Smarty.class.php';

/**
 * カレンダーＨＴＭＬを作成する
 */
class Components_Calendar_Weeklist extends Components_Calendar_Controller
{
	/** @var テンプレートファイル名 */
	const TEMPLATE_DESIGN = 'design.inc';

	/** コントロールネーム：学年選択チェックボックス */
	const NAME_AGE_CHECKBOX = 'AGE';

	/** @var 年 */
	protected $_iYearNum;
	/** @var 月 */
	protected $_iMonthNum;
	/** @var 左一列目曜日番号 */
	protected $_iStartYobiNum;
	/** @var 週毎のリスト配列 */
	protected $_aryWeekList;
	/** @var プリコンパイルフォルダー */
	protected $_strCompileDir;

	/**
	 * コンストラクタ
	 * Enter description here ...
	 * @param integer $iYearNum 年
	 * @param integer $iMonthNum 月
	 * @param integer $iStartYobiNum 左一列目の曜日番号
	 */
	public function __construct( $iYearNum='', $iMonthNum='', $iStartYobiNum = 1)
	{
		$this->setMgr(TRUE);

		$this->_strCompileDir = dirname(__FILE__) . '/../../data/templates_c';

		$objRequestDate = new Lib_Request_DateTime();
		$this->_iYearNum = $objRequestDate->getYearFromYMD();
		$this->_iMonthNum = $objRequestDate->getMonthFromYMD();
		$this->_iStartYobiNum = $iStartYobiNum;
		$this->_aryWeekList = array();
		$this->_MapSchedule();
	}

	/**
	 * fetch
	 * Enter description here ...
	 * @param string $strTemplateName テンプレートファイル名
	 * @param string $strCompileDir コンパイルディレクトリパス
	 */
	public function fetch( $strTemplateName="", $strCompileDir="" )
	{
		$this->_createWeekList();

		/** テンプレートファイル名初期値設定 */
		if ( $strTemplateName == '' ) {
			$strTemplateName = self::TEMPLATE_NAME_DESIGN;
		}
		/** コンパイルディレクトリ初期値設定 */
		if ( $strCompileDir == '' ) {
			$strCompileDir = $this->_strCompileDir;
		}

		// smartyインスタンス作成
		$objSmarty = new smarty;
		$objSmarty->template_dir = dirname( __FILE__ );
		$objSmarty->compile_dir	= $strCompileDir;
		$objSmarty->compile_id = 'componentes_calendar';
		$objSmarty->assign( 'aryAllWeekList', $this->_aryWeekList );
		$objSmarty->assign( 'year', $this->_iYearNum );
		$objSmarty->assign( 'month', sprintf('%d',$this->_iMonthNum) );
		$objSmarty->assign( 'strBasePath', $this->_strBasePath );
		$objSmarty->assign( 'bMgr', $this->_bMgr );

		$strHtml = '';
		/** テンプレートファイル名が初期値の場合のみフェッチ */
		if ( $strTemplateName == self::TEMPLATE_NAME_DESIGN ) {
			$strHtml = $objSmarty->fetch( $strTemplateName );
		}

		return $strHtml;
	}

	/**
	 * 週毎のリスト配列を作成する
	 * Enter description here ...
	 */
	protected function _createWeekList()
	{
		$this->_aryWeekList = array();

		// 第一週設定（先月余剰枠有り）
		$this->_aryWeekList[0] = $this->_createFirstWeekInfo();

		$aryWeekInfo = array();

		// 第二週目の表示開始曜日の日付を求める
		$iDay = $this->_aryWeekList[0][6]['DAYNUM'] + 1;

		// 当月最終日番号を求める
		$iLastDay = $this->getMonthEndDay( $this->_iYearNum, $this->_iMonthNum );

		/***
		 * 当月最終日までの週情報を設定する
		 */
		while ( $iDay <= $iLastDay ) {
			$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $iDay, $this->_iYearNum );
			$iYobiNum = date('w', $iTimeStamp);
			$strHolidayName 	= $this->getHolidayName( $this->_iYearNum, $this->_iMonthNum, $iDay );
			$strSched 			= $this->editSchedList( $this->getSchedInfo( $this->_iYearNum, $this->_iMonthNum, $iDay ) );
			$strCssClassName 	= $this->_getCssClass( $this->_iYearNum, $this->_iMonthNum, $iDay );
			$aryWeekInfo[] = array(
				self::KEY_DAYNUM		=> $iDay,
				self::KEY_YOBI			=> $iYobiNum,
				self::KEY_HOLIDAYNAME	=> $strHolidayName,
				self::KEY_SCHEDHTML		=> $strSched,
				self::KEY_CSSCLASS		=> $strCssClassName,
			);
			/**処理日が週最終曜日か判定する */
			if ( $iYobiNum == $this->getBeforYobiNum($this->_iStartYobiNum) ) {
				$this->_aryWeekList[] = $aryWeekInfo;
				$aryWeekInfo = array();
			}
			$iDay ++;
		}

		/***
		 * 翌月にまたぎ翌月第一週の週終了曜日までの週情報を設定する
		 */
		$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $iDay, $this->_iYearNum );
		$iYobiNum = date('w', $iTimeStamp);
		/** 第一週目について週終了曜日まで処理を行う */
		while ( $iYobiNum != $this->_iStartYobiNum ) {
			$iRealYear 	= date('Y', $iTimeStamp);
			$iRealMonth = date('n', $iTimeStamp);
			$iRealDay 	= date('j', $iTimeStamp);
			$strHolidayName 	= $this->getHolidayName( $iRealYear, $iRealMonth, $iRealDay );
			$strSched 			= $this->editSchedList( $this->getSchedInfo( $iRealYear, $iRealMonth, $iRealDay ) );
			$strCssClassName 	= $this->_getCssClass( $iRealYear, $iRealMonth, $iRealDay );
			$aryWeekInfo[] = array(
				self::KEY_DAYNUM		=> $iRealDay,
				self::KEY_YOBI			=> $iYobiNum,
				self::KEY_HOLIDAYNAME	=> $strHolidayName,
				self::KEY_SCHEDHTML		=> $strSched,
				self::KEY_CSSCLASS		=> 'neighbormonth',
			);
			$iDay ++;
			$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $iDay, $this->_iYearNum );
			$iYobiNum = date('w', $iTimeStamp);
		}
		/** 当月一日が週開始日でないか判定する */
		if ( count( $aryWeekInfo ) > 0 ){
			$this->_aryWeekList[] = $aryWeekInfo;
		}
	}

	/**
	 * 第一週の情報を返す
	 * Enter description here ...
	 */
	protected function _createFirstWeekInfo()
	{
		$aryFirstWeekInfo = array();

		// 当月初日の曜日
		$iFirstYobi = $this->getYobiNum( $this->_iYearNum, $this->_iMonthNum, 1 );

		/** 当月初日の曜日が、週開始曜日でないことを判定する */
		if ( $iFirstYobi != $this->_iStartYobiNum ) {
			$i = 0;
			$iLastMonthThisWeekDatetime = mktime( 0,0,0, $this->_iMonthNum, $i, $this->_iYearNum );

			// 先月の週開始曜日まで戻る
			while ( date( 'w', $iLastMonthThisWeekDatetime ) != $this->_iStartYobiNum ) {
				$i --;
				$iLastMonthThisWeekDatetime = mktime( 0,0,0, $this->_iMonthNum, $i, $this->_iYearNum );
			}

			// そこから先月末まで週情報を蓄積する
			while ( $i <= 0 ) {
				$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $i, $this->_iYearNum );
				$iRealYear 	= date('Y', $iTimeStamp);
				$iRealMonth = date('n', $iTimeStamp);
				$iRealDay 	= date('j', $iTimeStamp);
				$iRealYobi	= date('w', $iTimeStamp);

				$strHolidayName = $this->getHolidayName( $iRealYear, $iRealMonth, $iRealDay );

				$aryFirstWeekInfo[] = array(
					self::KEY_DAYNUM		=> $iRealDay,
					self::KEY_YOBI			=> $iRealYobi,
					self::KEY_HOLIDAYNAME	=> $strHolidayName,
					self::KEY_SCHEDHTML		=> '',
					self::KEY_CSSCLASS		=> 'neighbormonth',
				);
				$i ++;
			}
		}

		// 今月一日の情報を設定する
		$iTimeStamp 		= mktime(0,0,0,$this->_iMonthNum, 1, $this->_iYearNum );
		$strHolidayName 	= $this->getHolidayName( $this->_iYearNum, $this->_iMonthNum, 1 );
		$strSched 			= $this->editSchedList( $this->getSchedInfo( $this->_iYearNum, $this->_iMonthNum, 1 ) );
		$strCssClassName 	= $this->_getCssClass( $this->_iYearNum, $this->_iMonthNum, 1 );
		$aryFirstWeekInfo[] = array(
			self::KEY_DAYNUM		=> 1,
			self::KEY_YOBI			=> date('w', $iTimeStamp),
			self::KEY_HOLIDAYNAME	=> $strHolidayName,
			self::KEY_SCHEDHTML		=> $strSched,
			self::KEY_CSSCLASS		=> $strCssClassName,
		);

		// 当月二日から週終了曜日までの週情報を設定する
		$i = 2;
		$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $i, $this->_iYearNum );
		$iYobiNum = date('w', $iTimeStamp);
		/** 当月二日から週終了曜日までを処理する */
		while ( $iYobiNum != $this->_iStartYobiNum ) {
			$strHolidayName 	= $this->getHolidayName( $this->_iYearNum, $this->_iMonthNum, $i );
			$strSched 			= $this->editSchedList( $this->getSchedInfo( $this->_iYearNum, $this->_iMonthNum, $i ) );
			$strCssClassName 	= $this->_getCssClass( $this->_iYearNum, $this->_iMonthNum, $i );
			$aryFirstWeekInfo[] = array(
				self::KEY_DAYNUM		=> $i,
				self::KEY_YOBI			=> date('w', $iTimeStamp),
				self::KEY_HOLIDAYNAME	=> $strHolidayName,
				self::KEY_SCHEDHTML		=> $strSched,
				self::KEY_CSSCLASS		=> $strCssClassName,
			);
			$i ++;
			$iTimeStamp = mktime(0,0,0,$this->_iMonthNum, $i, $this->_iYearNum );
			$iYobiNum = date('w', $iTimeStamp);
		}
		return $aryFirstWeekInfo;
	}

	/**
	 * 一週間
	 * Enter description here ...
	 */
	protected function _isDayListEnough()
	{
		$iLastDay = $this->getMonthEndDay( $this->_iYearNum, $this->_iMonthNum );
		$i = 1;
		foreach ( $this->_aryDayList as $key=>$aryDayInfo ) {
			if ( $i != $key ) {
				return FALSE;
			}
			$i ++;
		}
		return TRUE;
	}

	protected function _getCssClass( $iYear, $iMonth, $iDay )
	{
		if ( $this->isHoliday( $iYear, $iMonth, $iDay ) !== FALSE ) {
			return self::CSS_CLASSNAME_HOLIDAY;
		}
		$iTimeStamp = mktime( 0,0,0, $iMonth, $iDay, $iYear );
		$iYobi = date('w', $iTimeStamp);
		if ( $iYobi == self::YOBI_SUNDAY ){
			return self::CSS_CLASSNAME_HOLIDAY;
		}
		if ( $iYobi == self::YOBI_SATURDAY ){
			return self::CSS_CLASSNAME_SATURDAY;
		}
		return self::CSS_CLASSNAME_WEEKDAY;
	}

	public static function editSchedList( $arySchedList )
	{
		$strHtml = '';
		foreach ( $arySchedList as $strSched ) {
			if ( $strHtml != '' ) {
				$strHtml .= '<br />';
			}
			$strHtml .= $strSched;
		}
		return $strHtml;
	}

	/**
	* スケジュールデータマッピング
	* Enter description here ...
	*/
	protected function _MapSchedule()
	{
		/** マッパークラス初期化 */
		$objDatasetScedule = new Components_Calendar_Mapper();
		$aryDatasetScedule = $objDatasetScedule->get($this->_getAgeForMap());

		/** 予定表示設置 */
		foreach ($aryDatasetScedule['LIST'] as $arySchedule ) {
			$sSchedDisp = $this->_mkScheduleLink($arySchedule);
			$this->addSchedInfo(
				$arySchedule[Models_Schedule_Xml_Controller::KEY_YEAR],
				$arySchedule[Models_Schedule_Xml_Controller::KEY_MONTH] ,
				$arySchedule[Models_Schedule_Xml_Controller::KEY_DAY],
				$sSchedDisp);
		}
	}

	/**
	 * 予定リンク作成
	 * Enter description here ...
	 * @param unknown_type $arySchedule
	 */
	protected function _mkScheduleLink($arySchedule)
	{
		/***
		 * スタッフ判定により、[参照｜編集]のＵＲＬ切り分け
		 */
		if ( $this->_bMgr == '1') {
			$sUrl = '/Schedule/edit/?ID=' . $arySchedule['ID'];
		} else {
			$sUrl  = '/Schedule/view/?ID=' . $arySchedule['ID'];
		}

		$sDispAge = str_replace('<br />', '/', $arySchedule['AGE_VIEW']);
		$sDispAge = str_replace('生', '', $sDispAge);
		if ( ($arySchedule['KIND'] == 'match') || ($arySchedule['KIND'] == 'game') ) {
			$sDispAge .= '(試)';
		}

		$sSchedDisp
		= '<strong>' . sprintf("[%5s]", $arySchedule['TIME_VIEW']) . '</strong>';

		$objA = new Smarty_Components_Anchor(
			$this->_strCompileDir,
			'yt',
			$sUrl,
			$sDispAge
		);

		return $sSchedDisp . ' ' . $objA->fetch();

		if ( $this->_bMgr === TRUE ) {

		}
	}

	/**
	* リクエストからスケジュールデータ用フィルタ年齢リストを取得する
	* Enter description here ...
	* @param unknown_type $aryAgeList
	* @return string|multitype:Ambigous <string>
	*/
	protected function _getAgeForMap($aryAgeList="")
	{
		if ( $aryAgeList == "" ) {
			if ( empty($_REQUEST[self::NAME_AGE_CHECKBOX]) ) {
				return "";
			}
			if ( is_array($_REQUEST[self::NAME_AGE_CHECKBOX])) {
				$aryAgeList = $_REQUEST[self::NAME_AGE_CHECKBOX];
			}
		}
		$aryAgeDictionary
		= array(
						'07'=>'U7',
						'08'=>'U8',
						'09'=>'U9',
						'10'=>'U10',
						'11'=>'U11',
						'12'=>'U12',
						'13'=>'U13',
						'14'=>'U14',
						'15'=>'U15',
						'16'=>'U16',
						'17'=>'U17',
						'18'=>'U18',
		);
		$aryResult = array();
		foreach ($aryAgeList as $sAge) {
			if ( !isset($aryAgeDictionary[$sAge] ) ) {
				continue;
			}
			$aryResult[] = $aryAgeDictionary[$sAge];
		}
		return $aryResult;
	}

}